﻿#ifndef STATEMACHINEDEFINITION_H
#define STATEMACHINEDEFINITION_H


#include <QObject>
#include <QMap>
#include <QVector>
#include <QRect>
#include <QPoint>

#include <QtCore/QJsonObject>
#include <QtCore/qglobal.h>

#define RSM_DEFINED_EXPORT Q_DECL_EXPORT

namespace StateMachineDefine
{
struct RSM_DEFINED_EXPORT Serializable
{
    Serializable() = default;
    Serializable(const Serializable &other) = default;
    Serializable & operator=(const Serializable &other) = default;

    virtual QJsonObject toJson() const = 0;
    virtual void fromJson(const QJsonObject  &) = 0;
    virtual ~Serializable() = default;

};

struct Transition;
struct StateMachine;
struct State;

struct RSM_DEFINED_EXPORT Project: Serializable{
    QString oid;
    QString path;
    QVector<QString> operatorList;    //工程中操作符Oid列表

    QJsonObject toJson() const override;
    void        fromJson(const QJsonObject &) override;
};

struct RSM_DEFINED_EXPORT Operator: Serializable{
    QString oid;
    QString name;
    QString projectOid;
    QString path;
    QVector<QString> stmList;    //操作符中顶层状态机Oid列表，记录他们之间的顺序

    QJsonObject toJson() const override;
    void        fromJson(const QJsonObject &) override;
};

struct RSM_DEFINED_EXPORT StateMachine : Serializable {
    using Ptr = QSharedPointer<StateMachine>;
    QString         oid;             //状态机oid
    QString         name;           //状态机名称
    QString         comment;        //状态机注释
    QString         projectid;      //工程id
    QString         poufilename;    //pou文件名
    QString         filename;       //语法文件名
    QString         projectpath;    // 工程路径
    QString         hierarchy;      //层级
    QString         initstate;      //初始状态
    QVector<QString>  statelist;    //状态列表
    QString         parentType;     //状态机的父节点类型Op/State
    QString         parentOid;      //状态机的父节点Oid
    QString         operatorOid;    //所属操作符oid
    bool            isSaved=true;   //是否被保存

    QJsonObject toJson() const override;
    void        fromJson(const QJsonObject &) override;

};

struct RSM_DEFINED_EXPORT POU : Serializable {
    QString oid;
    QString name;
    QString filePath;

    QJsonObject toJson() const override;
    void        fromJson(const QJsonObject &) override;
};

struct RSM_DEFINED_EXPORT State : Serializable {
    using Ptr = QSharedPointer<State>;
    QString         oid;             //状态oid
    QString         name;           //状态名
    QString         hierarchy;      //层级
    QString         comment;        //状态注释
    QString         parentid;       //所属状态机id
    QVector<QString>    stmList;    //状态机列表
    bool            isActive=false; //是否激活

//    struct POU {
//        QString oid;
//        QString name;
//        QString filePath;
//    };

    QVector<POU>    pouList;    //算法页列表
    bool            initial = false;
    bool            final = false;

    QVector<QString>  trans_strong;
    QVector<QString>  trans_weak;
    QVector<QString>  trans_sync;

    struct StateGE {
        QString present;
        QRect   rect;
    };

    StateGE     ge;
    QJsonObject toJson() const override;
    void        fromJson(const QJsonObject &) override;
};

enum TransKind {
    STRONG,
    WEAK,
    SYNCHRO,
};

enum TransHistory {
    RESTART,
    RESUME,
};

struct RSM_DEFINED_EXPORT Transition : Serializable {
    using Ptr =  QSharedPointer<Transition>;

    QString         oid;             //迁移oid
    QString         comment;        //注释
    QString         target;         //目标状态
    QString         source;         //起始状态
    TransKind       kind;           //迁移条件
    TransHistory    history;        //历史属性
    int             prior;          //优先级
    bool            isActive=false; //是否激活

    struct TransitionGE {
        QString present;
        QVector<QPoint> path; // start to end
    };

    TransitionGE    ge;

    // 设置和读取 condition, 自动进行 HTML 编码转换
    QString condition() const;
    void setCondition(const QString &condition);

    // 设置和读取 action, 自动进行 HTML 编码转换
    QString actions() const;
    void setActions(const QString &actions);

    QJsonObject toJson() const override;
    void        fromJson(const QJsonObject &) override;

    // 读写 HTML 编码的 condition 和 action
    QString rawConditon() const { return condition_;}
    void setRawConditon(const QString & cond) { condition_ = cond;}

    QString rawAction() const { return actions_;}
    void setRawAction(const QString &act) { actions_ = act;}
private:
    QString         condition_;  // html encoding, use getter & setter
    QString         actions_;  // html encoding
};

}

#endif // STATEMACHINEDEFINITION_H
